<template>
  <view class="container">
    <!-- 标题栏 -->
    <view class="header">
      <text class="title">BLE蓝牙测试</text>
      <text class="version">v1.0.0</text>
    </view>

    <!-- 状态卡片 -->
    <view class="status-grid">
      <view class="status-card">
        <text class="status-label">蓝牙状态</text>
        <text
          :class="[
            'status-value',
            adapterState.available ? 'success' : 'error',
          ]"
        >
          {{ adapterState.available ? "可用" : "不可用" }}
        </text>
      </view>

      <view class="status-card">
        <text class="status-label">连接状态</text>
        <text :class="['status-value', getConnectionStatusClass()]">
          {{ getConnectionStatusText() }}
        </text>
      </view>

      <view class="status-card">
        <text class="status-label">搜索状态</text>
        <text :class="['status-value', isScanning ? 'warning' : 'normal']">
          {{ isScanning ? "搜索中..." : "未搜索" }}
        </text>
      </view>

      <view class="status-card">
        <text class="status-label">监听状态</text>
        <text
          :class="['status-value', notificationEnabled ? 'success' : 'normal']"
        >
          {{
            notificationEnabled
              ? `监听中(${
                  notifyCharacteristics.filter((c) => c.enabled).length
                })`
              : "未监听"
          }}
        </text>
      </view>
    </view>

    <!-- 操作按钮 -->
    <view class="button-group">
      <button class="main-btn primary" @tap="initBLE" :disabled="isInitialized">
        {{ isInitialized ? "蓝牙已初始化" : "初始化蓝牙" }}
      </button>

      <view class="btn-row">
        <button
          class="action-btn success"
          @tap="startScan"
          :disabled="!isInitialized || isScanning"
        >
          {{ isScanning ? "搜索中..." : "开始搜索" }}
        </button>

        <button
          class="action-btn normal"
          @tap="stopScan"
          :disabled="!isScanning"
        >
          停止搜索
        </button>
      </view>

      <button
        class="main-btn danger"
        @tap="disconnect"
        :disabled="connectionState !== ConnectionState.CONNECTED"
      >
        断开连接
      </button>
    </view>

    <!-- 设备列表 -->
    <view class="section" v-if="discoveredDevices.length > 0">
      <view class="section-header">
        <text class="section-title"
          >发现的设备 ({{ discoveredDevices.length }})</text
        >
        <text class="clear-btn" @tap="clearDevices">清空</text>
      </view>

      <scroll-view class="device-list" scroll-y="true">
        <view
          v-for="device in discoveredDevices"
          :key="device.deviceId"
          class="device-item"
        >
          <view class="device-info" @tap="connectDevice(device)">
            <text class="device-name">
              {{ device.name || device.localName || "未知设备" }}
            </text>
            <text class="device-id"
              >{{ device.deviceId.substring(0, 20) }}...</text
            >
            <text class="device-rssi">{{ device.RSSI }}dBm</text>
          </view>
          <button
            class="connect-btn"
            @tap="connectDevice(device)"
            :disabled="connectionState === ConnectionState.CONNECTING"
          >
            {{
              connectionState === ConnectionState.CONNECTING ? "连接中" : "连接"
            }}
          </button>
        </view>
      </scroll-view>
    </view>

    <!-- 已连接设备信息 -->
    <view class="section" v-if="connectedDevice">
      <view class="section-header">
        <text class="section-title">已连接设备</text>
      </view>

      <view class="connected-info">
        <text class="connected-name">
          {{ connectedDevice.name || connectedDevice.localName || "未知设备" }}
        </text>
        <text class="connected-id">{{ connectedDevice.deviceId }}</text>

        <view class="action-buttons">
          <button class="small-btn" @tap="getDeviceServices">获取服务</button>
          <button class="small-btn" @tap="getRSSI">获取信号</button>
          <button class="small-btn" @tap="sendTestData">测试数据</button>
        </view>

        <view class="action-buttons" style="margin-top: 15rpx">
          <button
            :class="[
              'small-btn',
              'notify-btn',
              notificationEnabled ? 'notify-active' : '',
            ]"
            @tap="toggleNotifications"
            :disabled="deviceServices.length === 0"
          >
            {{ notificationEnabled ? "关闭监听" : "开启监听" }}
          </button>
          <button class="small-btn" @tap="setMTU" :disabled="!connectedDevice">
            设置MTU
          </button>
        </view>
      </view>

      <!-- 服务列表 -->
      <view v-if="deviceServices.length > 0" class="services-section">
        <text class="services-title"
          >设备服务 ({{ deviceServices.length }})</text
        >
        <scroll-view class="services-list" scroll-y="true">
          <view
            v-for="service in deviceServices"
            :key="service.uuid"
            class="service-item"
            @tap="getCharacteristics(service.uuid)"
          >
            <text class="service-uuid"
              >{{ service.uuid.substring(0, 30) }}...</text
            >
            <text class="service-type">{{
              service.isPrimary ? "主服务" : "次服务"
            }}</text>
          </view>
        </scroll-view>
      </view>
    </view>

    <!-- 数据发送 -->
    <view class="section">
      <view class="section-header">
        <text class="section-title">数据发送</text>
      </view>

      <view class="send-section">
        <input
          class="data-input"
          v-model="sendDataText"
          placeholder="输入十六进制数据，如: FF 01 02"
          maxlength="50"
        />
        <button
          class="send-btn"
          @tap="sendCustomData"
          :disabled="!connectedDevice"
        >
          发送
        </button>
      </view>
    </view>

    <!-- 日志区域 -->
    <view class="section">
      <view class="section-header">
        <text class="section-title">运行日志</text>
        <text class="clear-btn" @tap="clearLogs">清空</text>
      </view>

      <scroll-view
        class="logs-container"
        scroll-y="true"
        :scroll-top="scrollToTop"
      >
        <view
          v-for="log in reversedLogs"
          :key="log.id"
          :class="['log-item', log.type]"
        >
          <text class="log-time">{{ log.time }}</text>
          <text class="log-content">{{ log.message }}</text>
        </view>
      </scroll-view>
    </view>
  </view>
</template>

<script>
import {
  BLEManager,
  BLEEventType,
  ConnectionState,
  WriteType,
} from "@leir0ng/uniapp-ble-sdk";

export default {
  data() {
    return {
      ConnectionState, // 让模板能访问ConnectionState枚举
      bleManager: null,
      isInitialized: false,
      isScanning: false,
      connectionState: ConnectionState.DISCONNECTED,
      connectedDevice: null,
      discoveredDevices: [],
      deviceServices: [],
      notificationEnabled: false,
      notifyCharacteristics: [], // 存储可监听的特征值
      adapterState: {
        available: false,
        discovering: false,
      },
      sendDataText: "",
      logs: [],
      logId: 0,
      scrollToTop: 0,
    };
  },

  computed: {
    // 反转日志数组，最新的在上面
    reversedLogs() {
      return [...this.logs].reverse();
    },
  },

  onLoad() {
    this.addLog("info", "页面加载完成，准备创建BLE管理器...");
    this.createBLEManager();
  },

  onUnload() {
    this.addLog("info", "页面卸载，正在清理资源...");
    this.destroyBLE();
  },

  methods: {
    // 创建BLE管理器
    createBLEManager() {
      try {
        this.bleManager = new BLEManager({
          autoReconnect: true,
          reconnectInterval: 3000,
          maxReconnectAttempts: 3,
          connectionTimeout: 15000,
          allowDuplicatesKey: false,
          interval: 0,
        });

        this.setupEventListeners();
        this.addLog("success", "BLE管理器创建成功");
      } catch (error) {
        this.addLog("error", `创建BLE管理器失败: ${error.message}`);
      }
    },

    // 设置事件监听
    setupEventListeners() {
      // 适配器状态变化
      this.bleManager.on(BLEEventType.ADAPTER_STATE_CHANGE, (state) => {
        this.adapterState = {
          ...state,
        };
        this.addLog(
          "info",
          `蓝牙适配器状态: ${state.available ? "可用" : "不可用"}`
        );
      });

      // 发现设备
      this.bleManager.on(BLEEventType.DEVICE_FOUND, (device) => {
        const existingIndex = this.discoveredDevices.findIndex(
          (d) => d.deviceId === device.deviceId
        );
        if (existingIndex >= 0) {
          this.$set(this.discoveredDevices, existingIndex, device);
        } else {
          this.discoveredDevices.push(device);
        }

        const deviceName = device.name || device.localName || "未知设备";
        this.addLog("info", `发现设备: ${deviceName} (${device.RSSI}dBm)`);
      });

      // 连接状态变化
      this.bleManager.on(BLEEventType.CONNECTION_STATE_CHANGE, (event) => {
        this.connectionState = event.state;
        this.addLog("info", `连接状态变化: ${this.getConnectionStatusText()}`);

        if (event.state === ConnectionState.CONNECTED) {
          this.connectedDevice = this.bleManager.getConnectedDevice();
          this.addLog("success", `设备连接成功: ${event.deviceId}`);
          // 连接成功后自动获取服务并开启监听
          setTimeout(() => {
            this.getDeviceServices();
          }, 1000);
        } else if (event.state === ConnectionState.DISCONNECTED) {
          this.connectedDevice = null;
          this.deviceServices = [];
          this.notificationEnabled = false;
          this.notifyCharacteristics = [];
          this.addLog("warning", "设备连接断开");
        }
      });

      // 特征值变化 - 接收数据
      this.bleManager.on(BLEEventType.CHARACTERISTIC_VALUE_CHANGE, (data) => {
        const hexData = Array.from(new Uint8Array(data.value))
          .map((b) => b.toString(16).padStart(2, "0").toUpperCase())
          .join(" ");
        this.addLog("success", `接收数据: ${hexData}`);
      });

      // 错误处理
      this.bleManager.on(BLEEventType.ERROR, (error) => {
        this.addLog("error", `BLE错误 [${error.errCode}]: ${error.errMsg}`);
      });
    },

    // 初始化蓝牙
    async initBLE() {
      try {
        this.addLog("info", "正在初始化蓝牙适配器...");

        // 检查平台支持
        const platform = uni.getSystemInfoSync().platform;
        if (platform === "devtools") {
          this.addLog(
            "warning",
            "检测到开发者工具环境，蓝牙功能可能无法正常使用"
          );
        }

        await this.bleManager.initialize();
        this.isInitialized = true;
        this.addLog("success", "蓝牙适配器初始化成功");

        // 获取适配器状态
        const state = await this.bleManager.getAdapterState();
        this.adapterState = {
          ...state,
        };

        if (!state.available) {
          this.addLog("warning", "蓝牙不可用，请检查蓝牙是否开启");
          uni.showToast({
            title: "请开启蓝牙",
            icon: "none",
          });
        }
      } catch (error) {
        this.addLog("error", `蓝牙初始化失败: ${this.getErrorMessage(error)}`);
        uni.showToast({
          title: "蓝牙初始化失败",
          icon: "none",
        });
      }
    },

    // 开始搜索设备
    async startScan() {
      try {
        this.addLog("info", "开始搜索BLE设备...");
        this.discoveredDevices = [];
        this.isScanning = true;

        await this.bleManager.startDeviceDiscovery({
          minRSSI: -80,
          // services: ['180F'] // 可以指定服务UUID过滤
        });

        this.addLog("success", "设备搜索已开始，30秒后自动停止");
        uni.showToast({
          title: "开始搜索设备",
          icon: "success",
        });

        // 30秒后自动停止搜索
        setTimeout(() => {
          if (this.isScanning) {
            this.stopScan();
          }
        }, 30000);
      } catch (error) {
        this.isScanning = false;
        this.addLog("error", `开始搜索失败: ${this.getErrorMessage(error)}`);
        uni.showToast({
          title: "搜索失败",
          icon: "none",
        });
      }
    },

    // 停止搜索
    async stopScan() {
      try {
        await this.bleManager.stopDeviceDiscovery();
        this.isScanning = false;
        this.addLog(
          "info",
          `搜索结束，共发现 ${this.discoveredDevices.length} 个设备`
        );
      } catch (error) {
        this.addLog("error", `停止搜索失败: ${this.getErrorMessage(error)}`);
      }
    },

    // 连接设备
    async connectDevice(device) {
      try {
        const deviceName =
          device.name || device.localName || device.deviceId.substring(0, 8);
        this.addLog("info", `正在连接设备: ${deviceName}...`);

        // 停止搜索
        if (this.isScanning) {
          await this.stopScan();
        }

        uni.showLoading({
          title: "连接中...",
        });

        await this.bleManager.connect(device.deviceId);

        uni.hideLoading();
        uni.showToast({
          title: "连接成功",
          icon: "success",
        });
      } catch (error) {
        uni.hideLoading();
        this.addLog("error", `连接失败: ${this.getErrorMessage(error)}`);
        uni.showToast({
          title: "连接失败",
          icon: "none",
        });
      }
    },

    // 断开连接
    async disconnect() {
      try {
        uni.showLoading({
          title: "断开连接中...",
        });

        await this.bleManager.disconnect();
        uni.hideLoading();
        this.addLog("info", "主动断开连接");

        uni.showToast({
          title: "已断开连接",
          icon: "success",
        });
      } catch (error) {
        uni.hideLoading();
        this.addLog("error", `断开连接失败: ${this.getErrorMessage(error)}`);
      }
    },

    // 获取设备服务
    async getDeviceServices() {
      try {
        this.addLog("info", "正在获取设备服务...");
        // 清理之前的数据
        this.notifyCharacteristics = [];
        this.notificationEnabled = false;

        const services = await this.bleManager.getDeviceServices();
        this.deviceServices = services;
        this.addLog("success", `获取到 ${services.length} 个服务`);

        // 输出服务信息
        services.forEach((service) => {
          this.addLog(
            "info",
            `服务: ${service.uuid} (${service.isPrimary ? "主" : "次"})`
          );
        });

        // 自动获取主服务的特征值
        const primaryServices = services.filter((s) => s.isPrimary);
        if (primaryServices.length > 0) {
          this.addLog("info", `开始获取主服务特征值...`);
          for (const service of primaryServices) {
            await this.getCharacteristics(service.uuid);
          }

          // 自动开启监听
          if (this.notifyCharacteristics.length > 0) {
            this.addLog(
              "info",
              `发现 ${this.notifyCharacteristics.length} 个可监听特征值，准备自动开启监听...`
            );
            setTimeout(async () => {
              await this.toggleNotifications(true); // true表示自动开启
            }, 500); // 小延迟确保特征值收集完成
          } else {
            this.addLog("warning", "未发现可监听的特征值，无法自动开启监听");
          }
        }
      } catch (error) {
        this.addLog("error", `获取服务失败: ${this.getErrorMessage(error)}`);
      }
    },

    // 获取特征值
    async getCharacteristics(serviceId) {
      try {
        this.addLog("info", `获取服务特征值: ${serviceId}`);
        const characteristics = await this.bleManager.getDeviceCharacteristics(
          serviceId
        );

        this.addLog(
          "success",
          `服务 ${serviceId} 有 ${characteristics.length} 个特征值`
        );

        characteristics.forEach((char) => {
          const props = [];
          if (char.properties.read) props.push("读");
          if (char.properties.write) props.push("写");
          if (char.properties.notify) props.push("通知");
          if (char.properties.indicate) props.push("指示");

          this.addLog("info", `特征值: ${char.uuid} [${props.join(", ")}]`);

          // 收集可监听的特征值（仅限主服务）
          if (char.properties.notify || char.properties.indicate) {
            const service = this.deviceServices.find(
              (s) => s.uuid === serviceId
            );
            if (service && service.isPrimary) {
              this.notifyCharacteristics.push({
                serviceId,
                characteristicId: char.uuid,
                properties: char.properties,
                enabled: false,
              });
              this.addLog(
                "info",
                `发现主服务可监听特征值: ${char.uuid.substring(0, 8)}...`
              );
            }
          }
        });
      } catch (error) {
        this.addLog("error", `获取特征值失败: ${this.getErrorMessage(error)}`);
      }
    },

    // 启用/禁用通知
    async enableNotification(serviceId, characteristicId, enable = true) {
      try {
        await this.bleManager.notifyCharacteristicValueChange(
          serviceId,
          characteristicId,
          enable
        );

        // 更新特征值状态
        const char = this.notifyCharacteristics.find(
          (c) =>
            c.serviceId === serviceId && c.characteristicId === characteristicId
        );
        if (char) {
          char.enabled = enable;
        }

        this.addLog(
          "success",
          `已${
            enable ? "启用" : "禁用"
          }特征值通知: ${characteristicId.substring(0, 8)}...`
        );
      } catch (error) {
        this.addLog(
          "warning",
          `${enable ? "启用" : "禁用"}通知失败: ${this.getErrorMessage(error)}`
        );
      }
    },

    // 切换监听状态
    async toggleNotifications(isAuto = false) {
      try {
        if (this.notifyCharacteristics.length === 0) {
          this.addLog("warning", "没有找到可监听的特征值，请先获取服务");
          if (!isAuto) {
            uni.showToast({
              title: "没有可监听特征值",
              icon: "none",
            });
          }
          return;
        }

        const enable = !this.notificationEnabled;
        const actionText = enable ? "开启" : "关闭";
        const prefix = isAuto ? "自动" : "手动";

        this.addLog("info", `正在${prefix}${actionText}所有特征值监听...`);

        let successCount = 0;
        for (const char of this.notifyCharacteristics) {
          try {
            await this.enableNotification(
              char.serviceId,
              char.characteristicId,
              enable
            );
            successCount++;
            // 小延迟避免操作过快
            await new Promise((resolve) => setTimeout(resolve, 100));
          } catch (error) {
            console.error("Toggle notification error:", error);
          }
        }

        this.notificationEnabled = enable;
        this.addLog(
          "success",
          `${prefix}${actionText}监听完成，成功处理 ${successCount}/${this.notifyCharacteristics.length} 个特征值`
        );

        if (!isAuto) {
          uni.showToast({
            title: `${actionText}监听成功`,
            icon: "success",
          });
        }

        if (enable && successCount > 0) {
          this.addLog("info", "监听已开启，等待设备数据...");
        }
      } catch (error) {
        this.addLog(
          "error",
          `切换监听状态失败: ${this.getErrorMessage(error)}`
        );
        if (!isAuto) {
          uni.showToast({
            title: "操作失败",
            icon: "none",
          });
        }
      }
    },

    // 设置MTU
    async setMTU() {
      try {
        uni.showModal({
          title: "设置MTU",
          content: "请输入MTU值 (22-512)",
          editable: true,
          placeholderText: "247",
          success: async (res) => {
            if (res.confirm && res.content) {
              const mtu = parseInt(res.content);
              if (mtu < 22 || mtu > 512 || isNaN(mtu)) {
                this.addLog("error", "MTU值必须在22-512之间");
                uni.showToast({
                  title: "MTU值无效",
                  icon: "none",
                });
                return;
              }

              try {
                this.addLog("info", `正在设置MTU为 ${mtu}...`);
                await this.bleManager.setMTU(mtu);
                this.addLog("success", `MTU设置成功: ${mtu}`);
                uni.showToast({
                  title: "MTU设置成功",
                  icon: "success",
                });
              } catch (error) {
                this.addLog(
                  "error",
                  `MTU设置失败: ${this.getErrorMessage(error)}`
                );
                uni.showToast({
                  title: "MTU设置失败",
                  icon: "none",
                });
              }
            }
          },
        });
      } catch (error) {
        this.addLog("error", `设置MTU失败: ${this.getErrorMessage(error)}`);
      }
    },

    // 获取信号强度
    async getRSSI() {
      try {
        const rssi = await this.bleManager.getDeviceRSSI();
        this.addLog("info", `当前信号强度: ${rssi}dBm`);
        uni.showToast({
          title: `信号强度: ${rssi}dBm`,
          icon: "none",
        });
      } catch (error) {
        this.addLog(
          "error",
          `获取信号强度失败: ${this.getErrorMessage(error)}`
        );
      }
    },

    // 发送测试数据
    async sendTestData() {
      try {
        if (this.deviceServices.length === 0) {
          this.addLog("warning", "请先获取设备服务");
          return;
        }

        // 创建测试数据
        const testValue = Date.now() % 65535;
        const testData = new ArrayBuffer(4);
        const view = new DataView(testData);
        view.setUint32(0, testValue, true);

        const success = await this.sendDataToDevice(testData);
        if (success) {
          const hexData = Array.from(new Uint8Array(testData))
            .map((b) => b.toString(16).padStart(2, "0").toUpperCase())
            .join(" ");
          this.addLog("success", `测试数据发送成功: ${hexData}`);
          uni.showToast({
            title: "数据发送成功",
            icon: "success",
          });
        }
      } catch (error) {
        this.addLog(
          "error",
          `发送测试数据失败: ${this.getErrorMessage(error)}`
        );
      }
    },

    // 发送自定义数据
    async sendCustomData() {
      try {
        if (!this.sendDataText.trim()) {
          uni.showToast({
            title: "请输入要发送的数据",
            icon: "none",
          });
          return;
        }

        const data = this.hexToArrayBuffer(this.sendDataText);
        const success = await this.sendDataToDevice(data);

        if (success) {
          this.addLog("success", `数据发送成功: ${this.sendDataText}`);
          this.sendDataText = "";
          uni.showToast({
            title: "数据发送成功",
            icon: "success",
          });
        }
      } catch (error) {
        this.addLog("error", `发送数据失败: ${this.getErrorMessage(error)}`);
        uni.showToast({
          title: "发送失败",
          icon: "none",
        });
      }
    },

    // 通用发送数据方法
    async sendDataToDevice(data) {
      for (let service of this.deviceServices) {
        try {
          const characteristics =
            await this.bleManager.getDeviceCharacteristics(service.uuid);
          const writeChar = characteristics.find(
            (c) => c.properties.write || c.properties.writeNoResponse
          );

          if (writeChar) {
            const writeType = writeChar.properties.writeNoResponse
              ? WriteType.WRITE_NO_RESPONSE
              : WriteType.WRITE;

            await this.bleManager.writeCharacteristicValue(
              service.uuid,
              writeChar.uuid,
              data,
              writeType
            );

            return true;
          }
        } catch (error) {
          continue;
        }
      }

      this.addLog("warning", "未找到可写入的特征值");
      uni.showToast({
        title: "无可写特征值",
        icon: "none",
      });
      return false;
    },

    // 销毁BLE管理器
    async destroyBLE() {
      try {
        if (this.bleManager) {
          await this.bleManager.destroy();
          this.addLog("info", "BLE管理器已销毁");
        }
      } catch (error) {
        console.error("销毁BLE管理器失败:", error);
      }
    },

    // 清空设备列表
    clearDevices() {
      this.discoveredDevices = [];
      this.addLog("info", "已清空设备列表");
    },

    // 清空日志
    clearLogs() {
      this.logs = [];
      this.logId = 0;
    },

    // 添加日志
    addLog(type, message) {
      const log = {
        id: this.logId++,
        type,
        message,
        time: new Date().toLocaleTimeString(),
      };

      this.logs.push(log);

      // 限制日志数量
      if (this.logs.length > 50) {
        this.logs.shift();
      }

      // 自动滚动到顶部（最新日志）
      this.$nextTick(() => {
        this.scrollToTop = 0;
      });

      console.log(`[BLE-${type.toUpperCase()}] ${message}`);
    },

    // 获取连接状态文本
    getConnectionStatusText() {
      switch (this.connectionState) {
        case ConnectionState.DISCONNECTED:
          return "未连接";
        case ConnectionState.CONNECTING:
          return "连接中";
        case ConnectionState.CONNECTED:
          return "已连接";
        case ConnectionState.DISCONNECTING:
          return "断开中";
        default:
          return "未知";
      }
    },

    // 获取连接状态样式类
    getConnectionStatusClass() {
      switch (this.connectionState) {
        case ConnectionState.CONNECTED:
          return "success";
        case ConnectionState.CONNECTING:
        case ConnectionState.DISCONNECTING:
          return "warning";
        default:
          return "error";
      }
    },

    // 获取错误信息
    getErrorMessage(error) {
      if (typeof error === "string") return error;
      return error.message || error.errMsg || JSON.stringify(error);
    },

    // 十六进制转ArrayBuffer
    hexToArrayBuffer(hex) {
      // 清理输入，移除空格和非十六进制字符
      const cleanHex = hex.replace(/[^0-9A-Fa-f]/g, "");
      const bytes = cleanHex.match(/.{1,2}/g) || [];

      const buffer = new ArrayBuffer(bytes.length);
      const view = new Uint8Array(buffer);

      bytes.forEach((byte, index) => {
        view[index] = parseInt(byte, 16);
      });

      return buffer;
    },
  },
};
</script>

<style lang="scss">
.container {
  padding: 20rpx;
  background-color: #f8f8f8;
  min-height: 100vh;
}

.header {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  padding: 40rpx 30rpx;
  border-radius: 20rpx;
  margin-bottom: 30rpx;
  text-align: center;
  box-shadow: 0 8rpx 25rpx rgba(102, 126, 234, 0.3);
}

.title {
  color: #fff;
  font-size: 36rpx;
  font-weight: bold;
  display: block;
}

.version {
  color: rgba(255, 255, 255, 0.8);
  font-size: 24rpx;
  margin-top: 10rpx;
  display: block;
}

.status-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  margin-bottom: 30rpx;
  gap: 15rpx;
}

.status-card {
  background: #fff;
  padding: 25rpx 20rpx;
  border-radius: 15rpx;
  text-align: center;
  box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);
}

.status-label {
  font-size: 24rpx;
  color: #999;
  display: block;
  margin-bottom: 10rpx;
}

.status-value {
  font-size: 26rpx;
  font-weight: bold;
  display: block;

  &.success {
    color: #52c41a;
  }

  &.error {
    color: #ff4d4f;
  }

  &.warning {
    color: #faad14;
  }

  &.normal {
    color: #1890ff;
  }
}

.button-group {
  margin-bottom: 30rpx;
}

.main-btn {
  width: 100%;
  height: 88rpx;
  border: none;
  border-radius: 15rpx;
  font-size: 30rpx;
  font-weight: bold;
  margin-bottom: 20rpx;
  color: #fff;

  &.primary {
    background: linear-gradient(135deg, #1890ff, #096dd9);
    box-shadow: 0 4rpx 15rpx rgba(24, 144, 255, 0.4);
  }

  &.danger {
    background: linear-gradient(135deg, #ff4d4f, #cf1322);
    box-shadow: 0 4rpx 15rpx rgba(255, 77, 79, 0.4);
  }

  &:disabled {
    background: #d9d9d9 !important;
    color: #999 !important;
    box-shadow: none !important;
  }
}

.btn-row {
  display: flex;
  gap: 15rpx;
  margin-bottom: 20rpx;
}

.action-btn {
  flex: 1;
  height: 70rpx;
  border: none;
  border-radius: 12rpx;
  font-size: 26rpx;
  color: #fff;

  &.success {
    background: linear-gradient(135deg, #52c41a, #389e0d);
  }

  &.normal {
    background: linear-gradient(135deg, #13c2c2, #08979c);
  }

  &:disabled {
    background: #d9d9d9 !important;
    color: #999 !important;
  }
}

.section {
  background: #fff;
  border-radius: 15rpx;
  margin-bottom: 30rpx;
  box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08);
  overflow: hidden;
}

.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 25rpx 30rpx;
  border-bottom: 1rpx solid #f0f0f0;
}

.section-title {
  font-size: 28rpx;
  font-weight: bold;
  color: #333;
}

.clear-btn {
  font-size: 24rpx;
  color: #1890ff;
  padding: 10rpx 20rpx;
  background: #f0f9ff;
  border-radius: 8rpx;
}

.device-list {
  max-height: 400rpx;
  padding: 0 30rpx;
  box-sizing: border-box;
}

.device-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 25rpx 0;
  border-bottom: 1rpx solid #f0f0f0;
  gap: 15rpx;

  &:last-child {
    border-bottom: none;
  }
}

.device-info {
  flex: 1;
  cursor: pointer;

  &:active {
    opacity: 0.7;
  }
}

.device-name {
  font-size: 28rpx;
  font-weight: bold;
  color: #333;
  display: block;
  margin-bottom: 8rpx;
}

.device-id {
  font-size: 22rpx;
  color: #999;
  display: block;
  margin-bottom: 5rpx;
}

.device-rssi {
  font-size: 24rpx;
  color: #666;
  display: block;
}

.connect-btn {
  padding: 12rpx 24rpx;
  background: linear-gradient(135deg, #1890ff, #096dd9);
  color: #fff;
  border: none;
  border-radius: 8rpx;
  font-size: 24rpx;
  min-width: 80rpx;
  height: 60rpx;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;

  &:disabled {
    background: #d9d9d9;
    color: #999;
  }

  &:active {
    transform: scale(0.95);
  }
}

.connected-info {
  padding: 30rpx;
}

.connected-name {
  font-size: 30rpx;
  font-weight: bold;
  color: #333;
  display: block;
  margin-bottom: 10rpx;
}

.connected-id {
  font-size: 24rpx;
  color: #999;
  display: block;
  margin-bottom: 25rpx;
}

.action-buttons {
  display: flex;
  gap: 15rpx;
}

.small-btn {
  flex: 1;
  height: 60rpx;
  background: #1890ff;
  color: #fff;
  border: none;
  border-radius: 10rpx;
  font-size: 24rpx;

  &.notify-btn {
    background: linear-gradient(135deg, #52c41a, #389e0d);

    &.notify-active {
      background: linear-gradient(135deg, #ff4d4f, #cf1322);
      animation: pulse 2s infinite;
    }

    &:disabled {
      background: #d9d9d9 !important;
      color: #999 !important;
    }
  }

  &:disabled {
    background: #d9d9d9;
    color: #999;
  }
}

.services-section {
  margin-top: 20rpx;
  padding: 0 30rpx 20rpx;
}

.services-title {
  font-size: 26rpx;
  font-weight: bold;
  color: #333;
  display: block;
  margin-bottom: 15rpx;
}

.services-list {
  max-height: 300rpx;
}

.service-item {
  padding: 20rpx;
  background: #f9f9f9;
  border-radius: 10rpx;
  margin-bottom: 10rpx;

  &:active {
    background: #e6f7ff;
  }
}

.service-uuid {
  font-size: 24rpx;
  color: #333;
  display: block;
  margin-bottom: 5rpx;
  word-break: break-all;
}

.service-type {
  font-size: 22rpx;
  color: #666;
}

.send-section {
  padding: 30rpx;
  display: flex;
  gap: 15rpx;
}

.data-input {
  flex: 1;
  height: 70rpx;
  padding: 0 20rpx;
  border: 1rpx solid #d9d9d9;
  border-radius: 10rpx;
  font-size: 26rpx;
  background: #fafafa;
}

.send-btn {
  width: 120rpx;
  height: 70rpx;
  background: #52c41a;
  color: #fff;
  border: none;
  border-radius: 10rpx;
  font-size: 26rpx;

  &:disabled {
    background: #d9d9d9;
    color: #999;
  }
}

.logs-container {
  max-height: 400rpx;
  background: #1e1e1e;
  padding: 20rpx;
  font-family: Consolas, Monaco, monospace;
}

.log-item {
  margin-bottom: 8rpx;
  font-size: 22rpx;
  display: flex;
  align-items: flex-start;
  gap: 15rpx;

  &.info .log-content {
    color: #fff;
  }

  &.success .log-content {
    color: #52c41a;
  }

  &.warning .log-content {
    color: #faad14;
  }

  &.error .log-content {
    color: #ff4d4f;
  }
}

.log-time {
  color: #888;
  flex-shrink: 0;
  width: 120rpx;
}

.log-content {
  flex: 1;
  word-break: break-all;
  line-height: 1.4;
}

// 监听按钮的脉动动画
@keyframes pulse {
  0% {
    transform: scale(1);
    opacity: 1;
  }

  50% {
    transform: scale(1.02);
    opacity: 0.9;
  }

  100% {
    transform: scale(1);
    opacity: 1;
  }
}
</style>
